import type { PropType } from 'vue'
import { defineComponent, computed, reactive, ref } from "vue";

function getPageY(e: MouseEvent | TouchEvent) {
  return 'touches' in e ? e.touches[0].pageY : e.pageY;
}

export default defineComponent({
  name: 'scroll-bar',
  props: {
    prefixCls: String,
    height: Number,
    scrollTop: Number,
    scrollHeight: Number,
    onScroll: Function as PropType<(scrollTop: number) => void>
  },
  setup(props, { attrs, expose }) {
    const { prefixCls } = props
    const state = reactive({})
    const showScroll = computed(() => {
      return props.scrollHeight > props.height
    })
    const thumbHeight = computed(() => {
      const r = props.height / props.scrollHeight
      let h = Math.min(props.height * r, props.height * .75)
      h = Math.max(h, 16)
      return h
    })

    const _scrollTop = ref(0)
    function getTop() {
      const range = props.height - thumbHeight.value
      // const top = (props.scrollTop || _scrollTop.value) / (props.scrollHeight - props.height) * range
      // return top
      const percent = _scrollTop.value / (props.scrollHeight - props.height)
      return _scrollTop.value + (percent * range)
    }

    // ======================= expose =======================
    expose({
      setScrollTop: val => _scrollTop.value = val
    })

    // ======================= Thumb =======================
    let startPageY = 0, startTop = 0
    function onMousedown(e: MouseEvent | TouchEvent) {
      startPageY = getPageY(e)
      startTop = getTop()
      window.addEventListener('mousemove', onMousemove)
      window.addEventListener('mouseup', onMouseup)
      window.addEventListener('touchmove', onMousemove)
      window.addEventListener('touchend', onMouseup)
    }
    function onMousemove(e: MouseEvent | TouchEvent) {
      const offsetY = getPageY(e) - startPageY
      const scrollTop = (startTop + offsetY) / (props.height - thumbHeight.value) * props.scrollHeight
      props.onScroll?.(scrollTop)
    }
    function onMouseup(e: MouseEvent | TouchEvent) {
      window.removeEventListener('mousemove', onMousemove)
      window.removeEventListener('mouseup', onMouseup)
      window.removeEventListener('touchmove', onMousemove)
      window.removeEventListener('touchend', onMouseup)
    }

    return () => {
      const top = getTop()
      // const style = `height:${thumbHeight.value}px; transform: translateY(${top}px);`
      const style = `position:absolute;height:${thumbHeight.value}px; top:${top}px;`

      return (
        <div v-show={showScroll.value} class={`${prefixCls}_scrollbar`}>
          <div class={`${prefixCls}_scrollbar-thumb`} style={style} onMousedown={onMousedown} onTouchstart={onMousedown}></div>
        </div>
      )
    }
  }
})